package com.yangyouli.unity_demo_server.server;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.yangyouli.unity_demo_server.server.serializeModel.FriendsApplication;
import com.yangyouli.unity_demo_server.server.serializeModel.PrivateWords;

public class DataSave {
	/**
	 * 好友申请读取后的过期时间
	 */
	public static final long APPLICATION_EXPIRE_TIME = 1000 * 60 * 60 * 48;
	/**
	 * 好友消息读取后的过期时间
	 */
	public static final long PRIVATE_WORDS_EXPIRE_TIME = 1000 * 60 * 60 * 48;
	
	private static DataSave instance;
	Logger log = Logger.getLogger(DataSave.class);
	
	/**
	 * 好友申请的消息，key 为 接收者的 id，value 为好友申请的集合
	 */
	private Map<Integer, List<FriendsApplication>> friendsApplicationMessageMap = new HashMap<>();
	/**
	 * 私信的消息，key 为接收者的id，value 中的 key 为私信中发送者的 id
	 */
	private Map<Integer, Map<Integer, List<PrivateWords>>> privateWordsMap = new HashMap<>();
	
	private DataSave () {
		new Thread() {
			@Override
			public void run() {
				log.info("消息清除线程启动");
				while (true) {
					try {
						Thread.sleep(1000 * 60 * 60 * 6);
						long currentTime = new Date().getTime();
						// 清除好友申请消息
						List<FriendsApplication> willDeleteFriendsApplication = new ArrayList<>();
						for (List<FriendsApplication> fl : friendsApplicationMessageMap.values()) {
							for (FriendsApplication f : fl) {
								// 消息已读且过期
								if (f.isRead() && f.getExpireTime() < currentTime - f.getApplicationTime()) {
									willDeleteFriendsApplication.add(f);
								}
							}
						}
						for (FriendsApplication f : willDeleteFriendsApplication) {
							removeFriendsApplicationMessage(f);
						}
						// 清除好友私信消息
						List<PrivateWords> willDeletePrivateWords = new ArrayList<>();
						for (Map<Integer, List<PrivateWords>> m : privateWordsMap.values()) {
							for (List<PrivateWords> pl : m.values()) {
								for (PrivateWords p : pl) {
									if (p.isRead() && p.getExpireTime() < currentTime - p.getSendTime()) {
										willDeletePrivateWords.add(p);
									}
								}
							}
						}
						for (PrivateWords p : willDeletePrivateWords) {
							removePrivateWordsMessage(p);
						}
					} catch (InterruptedException e) {
						log.error("消息清除线程发生异常", e);
					}
				}
			}
		}.start();;
	}
	
	public static DataSave getInstance () {
		if (instance == null) {
			synchronized (DataSave.class) {
				if (instance == null) {
					instance = new DataSave();
				}
			}
		}
		return instance;
	}
	
	/**
	 * 将特定用户(FriendsApplication 中对应的消息接收者)收到的好友申请消息放入消息队列
	 * @param f
	 */
	public void addFriendsApplicationMessage (FriendsApplication f) { 
		List<FriendsApplication> l = friendsApplicationMessageMap.get(f.getRespondentUserId());
		if (l == null) {
			synchronized (friendsApplicationMessageMap) {
				if (l == null) {
					l = new LinkedList<>();
					l.add(f);
					friendsApplicationMessageMap.put(f.getRespondentUserId(), l);
				}
			}
		} else {
			for (int i = 0; i < l.size(); i++) {
				if (l.get(i).getApplicantUserId() == f.getApplicantUserId()) {
					// 重复，覆盖掉，不执行之后的语句
					synchronized (friendsApplicationMessageMap) {
						l.set(i, f);
					}
					return;
				}
			}
			synchronized (friendsApplicationMessageMap) {
				l.add(f);
			}
		}
	}
	
	/**
	 * 移除特定用户（FriendsApplication 中对应的接收者）接收到的某条好友申请消息
	 * @param userId
	 * @param f
	 */
	public void removeFriendsApplicationMessage (FriendsApplication f) {
		List<FriendsApplication> l = friendsApplicationMessageMap.get(f.getRespondentUserId());
		synchronized (friendsApplicationMessageMap) {
			if (l != null) {
				l.remove(f);
			}
		}
	}
	
	/**
	 * 根据接收者与申请者的 id 查找申请对象
	 * @param reciveUserId
	 * @param applicationUserId
	 * @return
	 */
	public FriendsApplication getFriendsApplication (int reciveUserId, int applicationUserId) {
		List<FriendsApplication> l = friendsApplicationMessageMap.get(reciveUserId);
		for (FriendsApplication a : l) {
			if (a.getRespondentUserId() == reciveUserId && a.getApplicantUserId() == applicationUserId) {
				return a;
			}
		}
		return null;
	}
	
	/**
	 * 得到 id 为 userId 的用户的所有好友申请消息集合
	 * @param userId
	 * @return
	 */
	public List<FriendsApplication> getFriendsApplicationMessage (int userId) {
		return friendsApplicationMessageMap.get(userId);
	}
	
	/**
	 * 将私信消息放入消息队列
	 * @param reciverUserId
	 * @param p
	 */
	public void addPrivateWordsMessage (PrivateWords p) { 
		Map<Integer, List<PrivateWords>> m = privateWordsMap.get(p.getReciveUserId());
		if (m == null) {
			synchronized (privateWordsMap) {
				if (m == null) {
					m = new HashMap<>();
					List<PrivateWords> l = new ArrayList<>();
					l.add(p);
					m.put(p.getSendUserId(), l);
					privateWordsMap.put(p.getReciveUserId(), m);
				}
			}
		} else {
			List<PrivateWords> l = m.get(p.getSendUserId());
			synchronized (privateWordsMap) {
				if (l == null) {
					l = new ArrayList<>();
					l.add(p);
					m.put(p.getSendUserId(), l);
				} else {
					l.add(p);
				}
			}
		}
	}
	
	/**
	 * 移除特定用户（PrivateWords 中的接收者）接收的某条私信消息
	 * @param userId
	 * @param p
	 */
	public void removePrivateWordsMessage (PrivateWords p) {
		Map<Integer, List<PrivateWords>> m = privateWordsMap.get(p.getReciveUserId());
		if (m != null) {
			List<PrivateWords> l = m.get(p.getSendUserId());
			synchronized (privateWordsMap) {
				if (l != null) {
					l.remove(p);
				}
			}
		}
	}
	
	/**
	 * 得到特定接收者的与所有存在未读消息的用户的 id
	 * @param userId
	 * @return
	 */
	public Set<Integer> getHasNotReadPrivateWordsUserId (int userId) {
		Map<Integer, List<PrivateWords>> l = privateWordsMap.get(userId);
		if (l != null) {
			Set<Integer> hasNotReadNewsUserId = new HashSet<>();
			for (Integer i : l.keySet()) {
				for (PrivateWords p : l.get(i)) {
					if (!p.isRead()) {
						hasNotReadNewsUserId.add(i);
						break;
					}
				}
			}
			return hasNotReadNewsUserId;
		} else {
			return null;
		}
	}
	
	/**
	 * 得到接收者与某个用户的聊天信息，且按照时间排序好了
	 * @param reciverUserId
	 * @param sendUserId
	 * @return List<PrivateWords> 不会为空
	 */
	public List<PrivateWords> getPrivateWordsMessage (int reciverUserId, int sendUserId) {
		Map<Integer, List<PrivateWords>> recive = privateWordsMap.get(reciverUserId); // reciverUserId 接受到的消息
		Map<Integer, List<PrivateWords>> send = privateWordsMap.get(sendUserId); // sendUserId 接收到的消息
		List<PrivateWords> reciveList = null;
		List<PrivateWords> sendList = null;
		if (recive != null) {
			reciveList = recive.get(sendUserId);
		}
		if (send != null) {
			sendList = send.get(reciverUserId);
		}
		List<PrivateWords> result = new ArrayList<>();
		int recivePointer = 0;
		int sendPointer = 0;
		// 根据时间先后，将对话消息添加到 result 中
		if (reciveList != null && sendList != null) {
			while (recivePointer < reciveList.size() && sendPointer < sendList.size()) {
				if (reciveList.get(recivePointer).getSendTime() < sendList.get(sendPointer).getSendTime()) {
					result.add(reciveList.get(recivePointer++));
				} else {
					result.add(sendList.get(sendPointer++));
				}
			}
		} else if (reciveList != null) {
			result.addAll(reciveList);
			recivePointer = reciveList.size();
		} else if (sendList != null) {
			result.addAll(sendList);
			sendPointer = sendList.size();
		}
		
		while (reciveList != null && recivePointer < reciveList.size()) {
			result.add(reciveList.get(recivePointer++));
		}
		while (sendList != null && sendPointer < sendList.size()) {
			result.add(sendList.get(sendPointer++));
		}
		return result;
	}
}
